package com.dubbo;

import java.io.IOException;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

/**
 * @author caoqianhuan
 * @date 2022/9/16
 * @Description: 虚拟机参数：-Xmx20m(调整堆内存为20m)  -XXPrintGCDetails -verbose:gc(显示gc详细信息)
 */
public class SoftReferenceExample {
    private static final int FOUR_MB = 1024 * 1024 * 4;

    public static void main(String[] args) throws IOException, InterruptedException {
        /**
         *业务中需要加载图片时
         */
        //List<byte[]> image = new ArrayList<>();
        //for (int i = 0; i < 5; i++) {
        //    image.add(new byte[FOUR_MB]);
        //}
        softReferenceExample();
    }

    public static void softReferenceExample() throws IOException, InterruptedException {
        List<SoftReference<byte[]>> softReferenceList = new ArrayList<>();
        //软引用队列  当所关联的软引用对象 所引用的对象（new bytes[FOUR_MB]）被GC了  该软引用对象会被加入 这个应用队列
        ReferenceQueue<byte[]> referenceQueue = new ReferenceQueue<>();
        for (int i = 0; i < 5; i++) {
            //创建软引用并关联软应用队列
            SoftReference<byte[]> softReference = new SoftReference<>(new byte[FOUR_MB], referenceQueue);
            softReferenceList.add(softReference);
            System.out.println(softReferenceList.get(i).get());
        }
        //System.in.read();
        //System.gc();  不需要手动GC 堆内存紧张时 会自己进行垃圾回收y
        //遍历软引用队列 将那些无用的软引用移除
        Reference<? extends byte[]> poll = referenceQueue.poll();
        while (poll != null) {
            softReferenceList.remove(poll);
            referenceQueue.remove();
            poll = referenceQueue.poll();
        }
        for (Reference reference : softReferenceList) {
            System.out.println(reference.get());
        }
    }
}

/**运行结果
 * [B@4554617c
 * [B@74a14482
 * [B@1540e19d
 * [GC (Allocation Failure) [PSYoungGen: 2272K->488K(6144K)] 14560K->13112K(19968K), 0.0011084 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
 * [B@677327b6
 * [GC (Allocation Failure) --[PSYoungGen: 4696K->4696K(6144K)] 17320K->17440K(19968K), 0.0008426 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
 * [Full GC (Ergonomics) [PSYoungGen: 4696K->4478K(6144K)] [ParOldGen: 12744K->12690K(13824K)] 17440K->17168K(19968K), [Metaspace: 3323K->3323K(1056768K)], 0.0070871 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
 * [GC (Allocation Failure) --[PSYoungGen: 4478K->4478K(6144K)] 17168K->17168K(19968K), 0.0008078 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
 * [Full GC (Allocation Failure) [PSYoungGen: 4478K->0K(6144K)] [ParOldGen: 12690K->755K(8704K)] 17168K->755K(14848K), [Metaspace: 3323K->3323K(1056768K)], 0.0075107 secs] [Times: user=0.11 sys=0.00, real=0.01 secs]
 * [B@14ae5a5
 *
 * null
 * null
 * null
 * null
 * [B@14ae5a5
 * Heap
 *  PSYoungGen      total 6144K, used 5096K [0x00000000ff980000, 0x0000000100000000, 0x0000000100000000)
 *   eden space 5632K, 90% used [0x00000000ff980000,0x00000000ffe7a1b8,0x00000000fff00000)
 *   from space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
 *   to   space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
 *  ParOldGen       total 8704K, used 755K [0x00000000fec00000, 0x00000000ff480000, 0x00000000ff980000)
 *   object space 8704K, 8% used [0x00000000fec00000,0x00000000fecbcf18,0x00000000ff480000)
 *  Metaspace       used 3675K, capacity 4536K, committed 4864K, reserved 1056768K
 *   class space    used 405K, capacity 428K, committed 512K, reserved 1048576K
 *
 * Process finished with exit code 0
 */
